package com.entities.report.detail;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.transform.Transformers;

import com.core.managers.SessionFactoryManager;
import com.core.protocols.ICustomDatasourceDelegate;
import com.core.protocols.IReportExecuteDatasource;
import com.core.protocols.IServiceLayerDelegate;
import com.core.utils.IndexPath;
import com.core.utils.ListUtils;
import com.entities.report.servicelayer.ReportListLayer;
import com.model.project.ProjectTask;
import com.model.report.Report;


public class ReportExecuteController
        implements IServiceLayerDelegate, IReportExecuteDatasource {

	private ICustomDatasourceDelegate delegate;
	List <Map <String, Object>>       resultList;
	List <Object>                     resultNamesList;



	public List <?> getResultList () {

		return resultList;
	}



	public void setResultList ( List <Map <String, Object>> list ) {

		this.resultList = list;
	}



	public ICustomDatasourceDelegate getDelegate () {

		return delegate;
	}



	public void setDelegate ( ICustomDatasourceDelegate delegate ) {

		this.delegate = delegate;
	}



	public void executeReportById ( String reportId ) {

		Integer result = null;
		try {
			result = Integer.parseInt(reportId);
		} catch ( NumberFormatException e ) {
			result = null;
		}

		ReportListLayer reportListLayer = new ReportListLayer();
		reportListLayer.objectByUNID(result, null, this);
	}



	@SuppressWarnings({
	        "rawtypes", "unchecked"
	})
	@Override
	public <T> void responseResponseItemsList ( List <T> items,
	                                            Object request,
	                                            Exception exception ) {

		T item = ListUtils.listItemAtIndex(items, 0);

		resultNamesList = null;
		if ( item == null ) {
			return;
		}

		Report report = (Report) item;
		String sql = report.getSqlScript();
		if ( sql == null ) {
			return;
		}
		if ( sql.length() == 0 ) {
			return;
		}


		Session session = SessionFactoryManager.sharedInstance().openSession();
		if ( session == null ) {
			return;
		}
		SQLQuery sqlQuery = null;
		try {
			Transaction transaction = session.beginTransaction();
			try {


				String sqlComplex = sql;
				sqlQuery = session.createSQLQuery(sqlComplex);
				 sqlQuery.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);

				this.resultList = new ArrayList <Map <String, Object>>();
				List <?> list = sqlQuery.list();
				Set <String> names = new HashSet <String>();
				Iterator <?> it = list.iterator();
				while ( it.hasNext() ) {
					Map map = (Map) it.next();
					this.resultList.add(map);
					Iterator <String> it1 = map.keySet().iterator();
					while ( it1.hasNext() ) {
						names.add(it1.next());
					}
				}

				Object[] namesArray = names.toArray();
				this.resultNamesList = Arrays.asList(namesArray);


				transaction.commit();
			} catch ( Exception e ) {
				if ( transaction.isActive() ) {
					transaction.rollback();
				}
			} finally {
				if ( delegate != null ) {
					delegate.refreshContent();
				}

			}
		} finally {
			session.close();
		}



	}



	@Override
	public int numberOfItems () {

		if ( resultList == null ) {
			return 0;
		} else {
			return this.resultList.size();
		}
	}



	@Override
	public Object itemAtIndexPath ( IndexPath indexPath ) {

		Map <String, Object> map = (Map <String, Object>) this.resultList.get(indexPath.getRow());
		String key = (String) this.resultNamesList.get(indexPath.getCol());
		return map.get(key);
	}



	@Override
	public int numberOfColumns () {

		if ( this.resultNamesList == null ) {
			return 0;
		} else {
			return this.resultNamesList.size();
		}
	}



	@Override
	public String columnAtIndex ( int index ) {

		if ( this.resultNamesList == null ) {
			return null;
		} else {
			return (String) this.resultNamesList.get(index);
		}
	}



	// @Override
	// public Object itemAtIndex ( int index ) {
	//
	// return this.resultList.get(index);
	// }



}
